package sys_ctrl

import (
	"net/http"
	"ubt-aio-service/app/mod/sys_mod"
	"ubt-aio-service/app/pkg/parse"
	"ubt-aio-service/app/serv/sys_serv"
	"ubt-aio-service/app/utils"
)

type sysMenu struct{}

var SysMenuCtrl sysMenu

// Save 保存菜单
func (c *sysMenu) Save(r *http.Request, w http.ResponseWriter) {
	// 通过头部请求的token获取用户信息
	token := r.Header.Get(utils.Token)
	userInfo := sys_serv.GetUserInfo(token)
	if userInfo == nil {
		utils.ToJson(w, utils.NoLogin)
		return
	}
	req := &sys_mod.SysMenuSaveReq{}
	// 将请求的参数转换为请求结构体
	if err := parse.Parse(r, req); err != "" {
		utils.ToJson(w, &utils.ResJson{Code: utils.ParamErr.Code, Msg: err})
		return
	}
	// 过滤关键参数值中的非法字符
	req.MenuId = utils.InputFilter(req.MenuId, true)
	req.MenuName = utils.InputFilter(req.MenuName, true)
	req.MenuCode = utils.InputFilter(req.MenuCode, true)
	req.ParentId = utils.InputFilter(req.ParentId, true)
	req.Url = utils.InputFilter(req.Url, true)
	req.Icon = utils.InputFilter(req.Icon, true)
	if req.MenuId == req.ParentId {
		utils.ToJson(w, utils.ParentErr)
		return
	}
	// 判断编码是否重复
	extVo := &sys_mod.SysMenuExtVo{MenuId: req.MenuId, MenuCode: req.MenuCode}
	if ext := sys_serv.SysMenuServ.Exists(extVo); ext {
		utils.ToJson(w, utils.Exists)
		return
	}
	var (
		res  *utils.ResJson
		kind uint8
	)
	if req.MenuId == "" {
		// 新增
		res = sys_serv.SysMenuServ.Add(req)
		kind = 1
	} else {
		// 修改
		res = sys_serv.SysMenuServ.Update(req)
		kind = 3
	}
	if res.Code == utils.Succeed.Code {
		logReq := &sys_mod.SysLogSaveReq{UserId: userInfo.UserId, MenuCode: utils.SysMenu, IpAddr: userInfo.ClientIp, Kind: kind}
		sys_serv.SysLogServ.Add(logReq)
	}
	utils.ToJson(w, res)
}

// Deletes 删除菜单
func (c *sysMenu) Deletes(r *http.Request, w http.ResponseWriter) {
	// 通过头部请求的token获取用户信息
	token := r.Header.Get(utils.Token)
	userInfo := sys_serv.GetUserInfo(token)
	if userInfo == nil {
		utils.ToJson(w, utils.NoLogin)
		return
	}
	// 将请求的参数转换为请求结构体
	req := &sys_mod.SysMenuDelsReq{}
	// 将请求的参数转换为请求结构体
	if err := parse.Parse(r, req); err != "" {
		utils.ToJson(w, &utils.ResJson{Code: utils.ParamErr.Code, Msg: err})
		return
	}
	// 过滤关键参数值中的非法字符
	req.MenuIds = utils.InputFilter(req.MenuIds, true)
	res := sys_serv.SysMenuServ.Deletes(req)
	if res.Code == utils.Succeed.Code {
		// 同时删除菜单下的按钮数据
		ch := make(chan int)
		go sys_serv.SysBtnServ.DelByMenu(ch, req.MenuIds)
		ch <- 1
		logReq := &sys_mod.SysLogSaveReq{UserId: userInfo.UserId, MenuCode: utils.SysMenu, IpAddr: userInfo.ClientIp, Kind: 2}
		sys_serv.SysLogServ.Add(logReq)
	}
	utils.ToJson(w, res)
}

// One 获取菜单详情
func (c *sysMenu) One(r *http.Request, w http.ResponseWriter) {
	// 通过头部请求的token获取用户信息
	token := r.Header.Get(utils.Token)
	userInfo := sys_serv.GetUserInfo(token)
	if userInfo == nil {
		utils.ToJson(w, utils.NoLogin)
		return
	}
	// 过滤关键参数值中的非法字符
	u := r.URL.Query()
	if u == nil {
		utils.ToJson(w, utils.ParamErr)
		return
	}
	menuId := u.Get("menuId")
	menuId = utils.InputFilter(menuId, true)
	if menuId == "" || len(menuId) != 21 {
		utils.ToJson(w, utils.ParamErr)
		return
	}
	res := sys_serv.SysMenuServ.One(menuId)
	utils.ToJson(w, res)
}

// List 获取菜单树状列表
func (c *sysMenu) List(r *http.Request, w http.ResponseWriter) {
	// 通过头部请求的token获取用户信息
	token := r.Header.Get(utils.Token)
	userInfo := sys_serv.GetUserInfo(token)
	if userInfo == nil {
		utils.ToJson(w, utils.NoLogin)
		return
	}
	res := sys_serv.SysMenuServ.List()
	utils.ToJson(w, res)
}

// Tree 获取菜单树状列表
func (c *sysMenu) Tree(r *http.Request, w http.ResponseWriter) {
	// 通过头部请求的token获取用户信息
	token := r.Header.Get(utils.Token)
	userInfo := sys_serv.GetUserInfo(token)
	if userInfo == nil {
		utils.ToJson(w, utils.NoLogin)
		return
	}
	res := sys_serv.SysMenuServ.Tree()
	utils.ToJson(w, res)
}

// Menu 获取菜单菜单树状菜单
func (c *sysMenu) Menu(r *http.Request, w http.ResponseWriter) {
	// 通过头部请求的token获取用户信息
	token := r.Header.Get(utils.Token)
	userInfo := sys_serv.GetUserInfo(token)
	if userInfo == nil {
		utils.ToJson(w, utils.NoLogin)
		return
	}
	menuCodes := userInfo.MenuCodes
	res := sys_serv.SysMenuServ.Menu(menuCodes)
	utils.ToJson(w, res)
}

// Select 获取树状菜单及按钮的列表
func (c *sysMenu) Select(r *http.Request, w http.ResponseWriter) {
	// 通过头部请求的token获取用户信息
	token := r.Header.Get(utils.Token)
	userInfo := sys_serv.GetUserInfo(token)
	if userInfo == nil {
		utils.ToJson(w, utils.NoLogin)
		return
	}
	res := sys_serv.SysMenuServ.Select(userInfo.MenuCodes, userInfo.Kind)
	if res.Code == utils.Succeed.Code {
		menuList := res.Data.([]map[string]any)
		if res = sys_serv.SysBtnServ.Select(); res.Code == utils.Succeed.Code {
			allBtnList := res.Data.([]map[string]any)
			for _, curMenu := range menuList {
				var btnList []map[string]any
				for _, curBtn := range allBtnList {
					if curMenu["menuId"].(string) == curBtn["menuId"].(string) {
						btnList = append(btnList, curBtn)
					}
				}
				curMenu["btnList"] = btnList
			}
		}
		utils.ToJson(w, &utils.ResJson{Code: res.Code, Msg: res.Msg, Data: menuList})
		return
	}
	utils.ToJson(w, utils.NoData)
}

// Sort 获取菜单数量，用于排序
func (c *sysMenu) Sort(r *http.Request, w http.ResponseWriter) {
	// 通过头部请求的token获取用户信息
	token := r.Header.Get(utils.Token)
	userInfo := sys_serv.GetUserInfo(token)
	if userInfo == nil {
		utils.ToJson(w, utils.NoLogin)
		return
	}
	// 过滤关键参数值中的非法字符
	u := r.URL.Query()
	if u == nil {
		utils.ToJson(w, utils.ParamErr)
		return
	}
	parentId := u.Get("parentId")
	parentId = utils.InputFilter(parentId, true)
	if parentId == "" || len(parentId) != 21 {
		utils.ToJson(w, utils.ParamErr)
		return
	}
	res := sys_serv.SysMenuServ.Sort(parentId)
	utils.ToJson(w, res)
}
